﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using SWM = System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SilverBullet.Effects;
using System.Windows.Media.Effects;

using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace SilverBullet.Graphics
{
    public class ClippedSpriteImage : Sprite
    {
        #region Fields
        SWM.TranslateTransform translate;
        System.Windows.Shapes.Rectangle rectangle;
        Texture2D texture;
        Color color;
        protected SWM.ImageBrush brush;
        DoubleRectangle sourceRectangle;
        TintEffect tintEffect;
        ShaderEffect mCustomEffect;
        #endregion

        #region Properties
        public Color Color
        {
            get
            {
                return color;
            }
            set
            {
                if (color != value)
                {
                    color = value;
                    if (mCustomEffect == null)
                    {
                        SetTintEffectAndColor();
                    }
                }
            }
        }

        public ShaderEffect CustomEffect
        {
            get { return mCustomEffect; }
            set
            {
                if (mCustomEffect != value)
                {
                    mCustomEffect = value;

                    if (value == null)
                    {
                        // If we're switching back from a custom effect, refresh the tintEffect
                        SetTintEffectAndColor();

                    }
                    else
                    {
                        rectangle.Effect = mCustomEffect;
                    }
                }
            }
        }

        public DoubleRectangle SourceRectangle
        {
            get
            {
                return sourceRectangle;
            }
            set
            {
                if (sourceRectangle.X != value.X ||
                    sourceRectangle.Y != value.Y)
                {
                    translate.X = -value.X;
                    translate.Y = -value.Y;
                }
                if (sourceRectangle.Width != value.Width ||
                    sourceRectangle.Height != value.Height)
                {
                    rectangle.Width = value.Width;
                    rectangle.Height = value.Height;
                }
                sourceRectangle = value;
            }
        }

        public virtual Texture2D Texture2D
        {
            get
            {
                return texture;
            }
            set
            {
                texture = value;
                if (value.VectorGraphic != null)
                {
                    Element = value.CloneVectorGraphic();
                    brush = null;
                }
                else
                    brush.ImageSource = value.ImageSource;
            }
        }

        #endregion

        #region Methods

        public ClippedSpriteImage()
            : base()
        {
            rectangle = new System.Windows.Shapes.Rectangle();
            brush = new SWM.ImageBrush();
            brush.Stretch = SWM.Stretch.None;
            translate = new SWM.TranslateTransform();
            brush.AlignmentX = SWM.AlignmentX.Left;
            brush.AlignmentY = SWM.AlignmentY.Top;
            brush.Transform = translate;
            rectangle.Fill = brush;
            Element = rectangle;
        }

        private void SetTintEffectAndColor()
        {
            if (color.R == 255 && color.G == 255 && color.B == 255)
            {
                rectangle.Effect = null;
                if (tintEffect != null)
                {
                    tintEffect.Release();
                }
                tintEffect = null;
                rectangle.Opacity = color.A / 255.0f;
                Element.Opacity = color.A / 255.0f;
            }
            else
            {
                if (tintEffect == null)
                {
                    tintEffect = TintEffect.Create();
                    rectangle.Effect = tintEffect;
                }
                tintEffect.Color = System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);
            }
        }

        public override void Dispose()
        {
            if (tintEffect != null) tintEffect.Release();
        }
        #endregion
    }
}
